/**
 ******************************************************************************
 * @file    eflash.h
 * @author  hyseim software Team
 * @date    18-Aug-2023
 * @brief   This file provides all the headers of the eflash functions.
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2020 Hyseim. Co., Ltd.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __EFLASH_H__
#define __EFLASH_H__

#include "common.h"
//#include <string.h>

#define EFLASHC_BASE 0x29000000

#define EFLASHC_WDATA_0_7   (EFLASHC_BASE+0x180000)
#define EFLASHC_WDATA_8_15  (EFLASHC_BASE+0x180008)
#define EFLASHC_ADDR        (EFLASHC_BASE+0x180010)
#define EFLASHC_WDATA_ECC   (EFLASHC_BASE+0x180018)
#define EFLASHC_OP          (EFLASHC_BASE+0x180020)
#define EFLASHC_TIMING      (EFLASHC_BASE+0x180040)
#define EFLASHC_SW_CTRL     (EFLASHC_BASE+0x180050)
#define EFLASHC_SW_CONF     (EFLASHC_BASE+0x180058)

#define EFLASHC_RDATA_FB0_0 (EFLASHC_BASE+0x180080)
#define EFLASHC_RDATA_FB0_1 (EFLASHC_BASE+0x180084)
#define EFLASHC_RDATA_FB0_2 (EFLASHC_BASE+0x180088)
#define EFLASHC_RDATA_FB0_3 (EFLASHC_BASE+0x18008c)
#define EFLASHC_RDATA_FB0_4 (EFLASHC_BASE+0x180090)
#define EFLASHC_RDATA_FB1_0 (EFLASHC_BASE+0x1800a0)
#define EFLASHC_RDATA_FB1_1 (EFLASHC_BASE+0x1800a4)
#define EFLASHC_RDATA_FB1_2 (EFLASHC_BASE+0x1800a8)
#define EFLASHC_RDATA_FB1_3 (EFLASHC_BASE+0x1800ac)
#define EFLASHC_RDATA_FB1_4 (EFLASHC_BASE+0x1800b0)

#define OS7_REG 0x7202211c
void delay1us(unsigned int data) {
  volatile unsigned int i,j;
  float x = 46.18261/15.0;
  float y ;
  y = (float)data;
  y = y/x;
  j = (unsigned int)y;

 // this is for fast sim with flash DISABLE_FLASH_TIMING_CHK
  *(volatile unsigned int *)(OS7_REG) = 0;
  for(i=0;i<j;i=i+1) { //100MHz core clk, 0.995us.
    *(volatile unsigned int *)(OS7_REG) = *(volatile unsigned int *)(OS7_REG)+1;//OS7
  }

}

void erase_ref(void )
{
  // test for erase ref
  word32(EFLASHC_SW_CONF, 1); //switch to sw mode
  word32(EFLASHC_SW_CTRL+4, 1 << 11 | 1 << (16 + 11)); // sw_fb1_sel   ;
  word32(EFLASHC_SW_CTRL+0, 1 << 11 | 1 << (16 + 11)); // sw_fb1_sel   ;

  word32(EFLASHC_SW_CTRL+4, 0 << 10 | 1 << (16 + 10)); // tmr;
  word32(EFLASHC_SW_CTRL+0, 0 << 10 | 1 << (16 + 10)); // tmr;
  word32(EFLASHC_SW_CTRL+4, 1 << 10 | 1 << (16 + 10)); // tmr;
  word32(EFLASHC_SW_CTRL+0, 1 << 10 | 1 << (16 + 10)); // tmr;
  word32(EFLASHC_SW_CTRL+4, 0 << 10 | 1 << (16 + 10)); // tmr;
  word32(EFLASHC_SW_CTRL+0, 0 << 10 | 1 << (16 + 10)); // tmr;

  word32(EFLASHC_SW_CTRL+4, 1 << 6 | 1 << (16 + 6) | 1 << 2 | 1 << (16 + 2)); // nvstr,se;
  word32(EFLASHC_SW_CTRL+0, 1 << 6 | 1 << (16 + 6) | 1 << 2 | 1 << (16 + 2)); // nvstr,se;

  word32(EFLASHC_SW_CTRL+4, 1 << 1 | 1 << (16 + 1) | 1 << 7 | 1 << (16 + 7)); // ye,ifren;
  word32(EFLASHC_SW_CTRL+0, 1 << 1 | 1 << (16 + 1) | 1 << 7 | 1 << (16 + 7)); // ye,ifren;

  word32(EFLASHC_SW_CTRL+4, 1 << 10 | 1 << (16 + 10)); // tmr;
  word32(EFLASHC_SW_CTRL+0, 1 << 10 | 1 << (16 + 10)); // tmr;
  word32(EFLASHC_SW_CTRL+4, 0 << 10 | 1 << (16 + 10)); // tmr;
  word32(EFLASHC_SW_CTRL+0, 0 << 10 | 1 << (16 + 10)); // tmr;

  word32(EFLASHC_SW_CTRL+4, 0 << 1 | 1 << (16 + 1) | 0 << 7 | 1 << (16 + 7)); // ye,ifren;
  word32(EFLASHC_SW_CTRL+0, 0 << 1 | 1 << (16 + 1) | 0 << 7 | 1 << (16 + 7)); // ye,ifren;

  word32(EFLASHC_SW_CTRL+4, 0 << 6 | 1 << (16 + 6) | 0 << 2 | 1 << (16 + 2)); // nvstr,se;
  word32(EFLASHC_SW_CTRL+0, 0 << 6 | 1 << (16 + 6) | 0 << 2 | 1 << (16 + 2)); // nvstr,se;
  delay1us(30);//#30us; // ttmh
  word32(EFLASHC_SW_CTRL+4, 1 << 0 | 1 << (16 + 0) | 1 << 3 | 1 << (16 + 3)); // xe,erase;
  word32(EFLASHC_SW_CTRL+0, 1 << 0 | 1 << (16 + 0) | 1 << 3 | 1 << (16 + 3)); // xe,erase;

  delay1us(8);//#8us; // tnvs
  word32(EFLASHC_SW_CTRL+4, 1 << 6 | 1 << (16 + 6)); // nvstr;
  word32(EFLASHC_SW_CTRL+0, 1 << 6 | 1 << (16 + 6)); // nvstr;

  delay1us(15000);//#10ms; // tre
  word32(EFLASHC_SW_CTRL+4, 0 << 3 | 1 << (16 + 3)); // erase;
  word32(EFLASHC_SW_CTRL+0, 0 << 3 | 1 << (16 + 3)); // erase;
  delay1us(5);//#5us; // tnvh

  word32(EFLASHC_SW_CTRL+4, 0 << 0 | 1 << (16 + 0) | 0 << 6 | 1 << (16 + 6)); // nvstr;
  word32(EFLASHC_SW_CTRL+0, 0 << 0 | 1 << (16 + 0) | 0 << 6 | 1 << (16 + 6)); // nvstr;

  word32(EFLASHC_SW_CONF, 0); //switch to hw mode
}

// M32/P16/I64
// ColMux 32/16WL perpage/ 64 information WL
// address 0x000000~0x07FFFF EFLASH0 MAINBLOCK
// address 0x080000~0x0FFFFF EFLASH1 MAINBLOCK
// address 0x100000~0x0003FF EFLASH0 INFOBLOCK
// address 0x180000~0x1803FF EFLASH1 INFOBLOCK
//0x1803F0~0x1803FF -> 0x70000F20 ~ 0x70000F2C
//page 256bytes
void page_erase(unsigned int paddress) // in main memory paddress is align  to byte. info memory paddress is wl(16 bytes) num. (0~63)
{
  unsigned int slice_sel ;
  unsigned int addr_sel  ;
  unsigned int info_sel  ;
  unsigned int ecc_var   ;
  slice_sel = 1 << 11;
  if ( paddress >= 0x180000) {
    info_sel = 1;
    addr_sel = EFLASHC_SW_CTRL + 4;
  } else if ( paddress >= 0x100000) {
    info_sel = 1;
    addr_sel = EFLASHC_SW_CTRL ;
  } else if ( paddress >= 0x80000) {
    info_sel = 0;
    addr_sel = EFLASHC_SW_CTRL + 4;
  } else {
    info_sel = 0;
    addr_sel = EFLASHC_SW_CTRL ;
  }
  if ( info_sel ) {
  //reg32(EFLASHC_ADDR) = (paddress&0x3F) << 9;
    reg32(EFLASHC_ADDR) = paddress&(0x3F<<9);
  } else {
    reg32(EFLASHC_ADDR) = paddress;
  }

  word32(addr_sel, // slice0
                        0 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                 info_sel << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
           slice_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  word32(EFLASHC_SW_CONF, 1); //switch to sw mode

  word32(addr_sel, // slice0
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        1 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                 info_sel << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  delay1us(10);//#8us;//tnvs

  word32(addr_sel, // slice0
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        1 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        1 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                 info_sel << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                     slice_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  delay1us(15000);//#10~20ms;//Terase

  word32(addr_sel, // slice0
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        1 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                 info_sel << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  delay1us(6);//#5us;//tnvh

  word32(addr_sel, // slice0
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                 info_sel << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                     slice_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  delay1us(6);//#10us/2;//Trcv/2

  word32(addr_sel, // slice0
                        0 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                 info_sel << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;
  delay1us(5);//#10us/2;//Trcv/2

  word32(EFLASHC_SW_CONF, 0); //switch to hw mode
}

//
void program_flash_slice0_single(unsigned int paddress, unsigned int *celldata)
{
  unsigned int slice_sel ;
  unsigned int addr_sel  ;
  unsigned int info_sel  ;
  unsigned int ecc_var   ;
  slice_sel = 1 << 11;
  if ( paddress >= 0x180000) {
    info_sel = 1;
    addr_sel = EFLASHC_SW_CTRL + 4;
  } else if ( paddress >= 0x100000) {
    info_sel = 1;
    addr_sel = EFLASHC_SW_CTRL ;
  } else if ( paddress >= 0x80000) {
    info_sel = 0;
    addr_sel = EFLASHC_SW_CTRL + 4;
  } else {
    info_sel = 0;
    addr_sel = EFLASHC_SW_CTRL ;
  }
  if ( info_sel ) {
    reg32(EFLASHC_ADDR) = paddress&0x7FFF;
  } else {
    reg32(EFLASHC_ADDR) = paddress;
  }
//reg32(EFLASHC_WDATA_0_7)        = celldata[0];
//reg32(EFLASHC_WDATA_0_7 + 0x4)  = celldata[1];
//reg32(EFLASHC_WDATA_8_15)       = celldata[2];
//reg32(EFLASHC_WDATA_8_15 + 0x4) = celldata[3];

  word32(addr_sel, // slice0
                        0 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                 info_sel << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
           slice_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  word32(EFLASHC_SW_CONF, 1); //switch to sw mode

  // get ecc first
  for(int i = 0; i < 4 ; i++ ) { // 4times to write 137bit
      reg32(EFLASHC_WDATA_0_7)        = celldata[0] ;
      reg32(EFLASHC_WDATA_0_7 + 0x4)  = celldata[1] ;
      reg32(EFLASHC_WDATA_8_15)       = celldata[2] ;
      reg32(EFLASHC_WDATA_8_15 + 0x4) = celldata[3] ;
      ecc_var = reg32(EFLASHC_WDATA_ECC) >> 16;
  }
  word32(addr_sel, // slice0
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        1 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                 info_sel << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  delay1us(10);//#8us;//tnvs

  word32(addr_sel, // slice0
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        1 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        1 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                 info_sel << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  delay1us(3);//#2us;//Tpgs

  for(int i = 0; i < 4 ; i++ ) { // 4times to write 137bit
    // grp0 34:0
    // grp1 69:35
    // grp2 104:60
    // grp3 136:105
    if ( i == 0 ) {
      reg32(EFLASHC_WDATA_0_7)        = celldata[0]             ;
      reg32(EFLASHC_WDATA_0_7 + 0x4)  = celldata[1] | 0xFFFFFFF8;
      reg32(EFLASHC_WDATA_8_15)       = celldata[2] | 0xFFFFFFFF;
      reg32(EFLASHC_WDATA_8_15 + 0x4) = celldata[3] | 0xFFFFFFFF;
      reg32(EFLASHC_WDATA_ECC)        = 0xFFFFFFFF;
    } else if ( i == 1 ) {
      reg32(EFLASHC_WDATA_0_7)        = celldata[0] | 0xFFFFFFFF;
      reg32(EFLASHC_WDATA_0_7 + 0x4)  = celldata[1] | 0x00000007;
      reg32(EFLASHC_WDATA_8_15)       = celldata[2] | 0xFFFFFFC0;
      reg32(EFLASHC_WDATA_8_15 + 0x4) = celldata[3] | 0xFFFFFFFF;
      reg32(EFLASHC_WDATA_ECC)        = 0xFFFFFFFF;
    } else if ( i == 2 ) {
      reg32(EFLASHC_WDATA_0_7)        = celldata[0] | 0xFFFFFFFF;
      reg32(EFLASHC_WDATA_0_7 + 0x4)  = celldata[1] | 0xFFFFFFFF;
      reg32(EFLASHC_WDATA_8_15)       = celldata[2] | 0x0000003F;
      reg32(EFLASHC_WDATA_8_15 + 0x4) = celldata[3] | 0xFFFFFE00;
      reg32(EFLASHC_WDATA_ECC)        = 0xFFFFFFFF;
    } else {
      reg32(EFLASHC_WDATA_0_7)        = celldata[0] | 0xFFFFFFFF;
      reg32(EFLASHC_WDATA_0_7 + 0x4)  = celldata[1] | 0xFFFFFFFF;
      reg32(EFLASHC_WDATA_8_15)       = celldata[2] | 0xFFFFFFFF;
      reg32(EFLASHC_WDATA_8_15 + 0x4) = celldata[3] | 0x000001FF;
      reg32(EFLASHC_WDATA_ECC)        = ecc_var ;
    }

  word32(addr_sel, // slice0
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        1 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        1 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        1 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                 info_sel << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  delay1us(12);//#8~16us;//Tprog

  word32(addr_sel, // slice0
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        1 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        1 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                 info_sel << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;
   }
  // delay 20ns Tpgh (ignored)
  word32(addr_sel, // slice0
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        1 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                 info_sel << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  delay1us(6);//#5us;//tnvh

  word32(addr_sel, // slice0
                        0 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                 info_sel << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  delay1us(10);//#10us;//Trcv

  word32(EFLASHC_SW_CONF, 0); //switch to hw mode
}

// len is size of char*8 due to performance info is not read in this function
void read_eflash(unsigned int paddress, unsigned char *celldata, unsigned int len)
{
  unsigned int slice_sel ;
  unsigned int addr_sel  ;
  const unsigned int info_sel  = 0;
  unsigned int ecc_var   ;
  unsigned int bursts    ;
  unsigned int ef1_sel   = 0;

  slice_sel = 1 << 11;
  if ( paddress >= 0x80000) {
    addr_sel = EFLASHC_SW_CTRL + 4;
    ef1_sel  = 1;
  } else {
    addr_sel = EFLASHC_SW_CTRL ;
    ef1_sel  = 0;
  }
  reg32(EFLASHC_ADDR) = paddress;

  bursts = len & 0xFFFFFFF8;

  word32(addr_sel, // slice0
                        0 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                 info_sel << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
           slice_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  word32(EFLASHC_SW_CONF, 1); //switch to sw mode

  for(int i =0 ; i<bursts ;i += 0x10 ) {
    reg32(EFLASHC_ADDR) = paddress;
    word32(addr_sel, // slice0
                          1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                          1 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                          0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                          0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                          0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                          0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                          0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                   info_sel << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                          0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                          0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                          1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                      slice_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

    // Txys = 2ns
    word32(addr_sel, // slice0
                          1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                          1 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                          1 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                          0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                          0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                          0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                          0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                   info_sel << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                          0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                          0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                          1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                      slice_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;
    //delay1us(1);
    // Tpws 5ns > 0.99, 10ns <= 0.99
    word32(addr_sel, // slice0
                          1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                          1 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                          0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                          0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                          0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                          0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                          0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                   info_sel << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                          0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                          0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                          1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                      slice_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

    // Tnws 2ns
    // Tacc 15.46ns > 0.99, 21.11ns <=0.99
    // Tcyc 20ns > 0.99, 30ns <=0.99
    if (ef1_sel) {
    //memcpy(celldata+i,EFLASHC_RDATA_FB1_0,16);
      *(volatile unsigned int *)(celldata+i+0x00) = *(volatile unsigned int *)(EFLASHC_RDATA_FB1_0);
      *(volatile unsigned int *)(celldata+i+0x04) = *(volatile unsigned int *)(EFLASHC_RDATA_FB1_1);
      *(volatile unsigned int *)(celldata+i+0x08) = *(volatile unsigned int *)(EFLASHC_RDATA_FB1_2);
      *(volatile unsigned int *)(celldata+i+0x0c) = *(volatile unsigned int *)(EFLASHC_RDATA_FB1_3);
    //*(celldata+i+0x04) = *(volatile unsigned int *)(EFLASHC_RDATA_FB1_0+0x10);
    } else {
    //memcpy(celldata+i,EFLASHC_RDATA_FB0_0,16);
      *(volatile unsigned int *)(celldata+i+0x00) = *(volatile unsigned int *)(EFLASHC_RDATA_FB0_0);
      *(volatile unsigned int *)(celldata+i+0x04) = *(volatile unsigned int *)(EFLASHC_RDATA_FB0_1);
      *(volatile unsigned int *)(celldata+i+0x08) = *(volatile unsigned int *)(EFLASHC_RDATA_FB0_2);
      *(volatile unsigned int *)(celldata+i+0x0c) = *(volatile unsigned int *)(EFLASHC_RDATA_FB0_3);
    //*(celldata+i+0x04) = *(volatile unsigned int *)(EFLASHC_RDATA_FB0_0+0x10);
    }
    paddress += 0x10;
  }

  //delay1us(1);//#10us;//Trcv

  word32(EFLASHC_SW_CONF, 0); //switch to hw mode
}

//
void read_eflash_wl(unsigned int paddress, unsigned int *celldata)
{
  unsigned int slice_sel ;
  unsigned int addr_sel  ;
  unsigned int info_sel  ;
  unsigned int ecc_var   ;
  slice_sel = 1 << 11;
  if ( paddress >= 0x180000) {
    info_sel = 1;
    addr_sel = EFLASHC_SW_CTRL + 4;
  } else if ( paddress >= 0x100000) {
    info_sel = 1;
    addr_sel = EFLASHC_SW_CTRL ;
  } else if ( paddress >= 0x80000) {
    info_sel = 0;
    addr_sel = EFLASHC_SW_CTRL + 4;
  } else {
    info_sel = 0;
    addr_sel = EFLASHC_SW_CTRL ;
  }
  if ( info_sel ) {
    reg32(EFLASHC_ADDR) = paddress&0x7FFF;
  } else {
    reg32(EFLASHC_ADDR) = paddress;
  }
//reg32(EFLASHC_WDATA_0_7)        = celldata[0];
//reg32(EFLASHC_WDATA_0_7 + 0x4)  = celldata[1];
//reg32(EFLASHC_WDATA_8_15)       = celldata[2];
//reg32(EFLASHC_WDATA_8_15 + 0x4) = celldata[3];

  word32(addr_sel, // slice0
                        0 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                 info_sel << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
           slice_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  word32(EFLASHC_SW_CONF, 1); //switch to sw mode

  word32(addr_sel, // slice0
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        1 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                 info_sel << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  // Txys = 2ns
  word32(addr_sel, // slice0
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        1 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        1 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                 info_sel << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;
  //delay1us(1);
  // Tpws 5ns > 0.99, 10ns <= 0.99
  word32(addr_sel, // slice0
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        1 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                 info_sel << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  // Tnws 2ns
  // Tacc 15.46ns > 0.99, 21.11ns <=0.99
  // Tcyc 20ns > 0.99, 30ns <=0.99
  if (0x80000 == (paddress & 0x80000)) {
    *(celldata+0x00) = *(volatile unsigned int *)(EFLASHC_RDATA_FB1_0);
    *(celldata+0x01) = *(volatile unsigned int *)(EFLASHC_RDATA_FB1_0+0x4);
    *(celldata+0x02) = *(volatile unsigned int *)(EFLASHC_RDATA_FB1_0+0x8);
    *(celldata+0x03) = *(volatile unsigned int *)(EFLASHC_RDATA_FB1_0+0xc);
    *(celldata+0x04) = *(volatile unsigned int *)(EFLASHC_RDATA_FB1_0+0x10);
  } else {
    *(celldata+0x00) = *(volatile unsigned int *)(EFLASHC_RDATA_FB0_0);
    *(celldata+0x01) = *(volatile unsigned int *)(EFLASHC_RDATA_FB0_0+0x4);
    *(celldata+0x02) = *(volatile unsigned int *)(EFLASHC_RDATA_FB0_0+0x8);
    *(celldata+0x03) = *(volatile unsigned int *)(EFLASHC_RDATA_FB0_0+0xc);
    *(celldata+0x04) = *(volatile unsigned int *)(EFLASHC_RDATA_FB0_0+0x10);
  }

  //delay1us(1);//#10us;//Trcv

  word32(EFLASHC_SW_CONF, 0); //switch to hw mode
}

void eflash_mass_erase ( unsigned char slice) { // 1 for slice0, 2 for slice1, 3 for both slice
  unsigned int slice0_sel ;
  unsigned int slice1_sel ;
  slice0_sel = ((slice&1) == 1)? 1 << 11 : 0;
  slice1_sel = ((slice&2) == 2)? 1 << 11 : 0;
  word32(EFLASHC_SW_CONF,1); //switch to sw mode

  if ( slice0_sel)
  word32(EFLASHC_SW_CTRL, // slice0
                        0 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                        0 << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice0_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  if ( slice1_sel)
  word32(EFLASHC_SW_CTRL+4, // slice0
                        0 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                        0 << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice1_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  if ( slice0_sel)
  word32(EFLASHC_SW_CTRL, // slice0
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        1 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                        0 << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice0_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  if ( slice1_sel)
  word32(EFLASHC_SW_CTRL+4, // slice1
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        1 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                        0 << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice1_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  if ( slice0_sel)
  word32(EFLASHC_SW_CTRL, // slice0
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        1 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        1 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                        0 << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice0_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  if ( slice1_sel)
  word32(EFLASHC_SW_CTRL+4, // slice1
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        1 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        1 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                        0 << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice1_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  if ( slice0_sel | slice1_sel) delay1us(120); //100us

  if ( slice0_sel)
  word32(EFLASHC_SW_CTRL, // slice0
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        1 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        1 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        1 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                        0 << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice0_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  if ( slice1_sel)
  word32(EFLASHC_SW_CTRL+4, // slice1
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        1 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        1 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        1 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                        0 << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice1_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  if ( slice0_sel | slice1_sel) printf("eflash mass erasing \n");
  if ( slice0_sel | slice1_sel) delay1us(12000); // 10-20ms

  if ( slice0_sel)
  word32(EFLASHC_SW_CTRL, // slice0
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        1 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        1 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                        0 << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice0_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  if ( slice1_sel)
  word32(EFLASHC_SW_CTRL+4, // slice1
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        1 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        1 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                        0 << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice1_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  if ( slice0_sel | slice1_sel) delay1us(120); //100us

  if ( slice0_sel)
  word32(EFLASHC_SW_CTRL, // slice0
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        1 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                        0 << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice0_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  if ( slice1_sel)
  word32(EFLASHC_SW_CTRL+4, // slice1
                        1 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        1 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                        0 << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice1_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  if ( slice0_sel)
  word32(EFLASHC_SW_CTRL, // slice0
                        0 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                        0 << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice0_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  if ( slice1_sel)
  word32(EFLASHC_SW_CTRL+4, // slice1
                        0 << 0  | 1 << (16 + 0  ) | //sw_fb0_xe    ;
                        0 << 1  | 1 << (16 + 1  ) | //sw_fb0_ye    ;
                        0 << 2  | 1 << (16 + 2  ) | //sw_fb0_se    ;
                        0 << 3  | 1 << (16 + 3  ) | //sw_fb0_erase ;
                        0 << 4  | 1 << (16 + 4  ) | //sw_fb0_mas1  ;
                        0 << 5  | 1 << (16 + 5  ) | //sw_fb0_prog  ;
                        0 << 6  | 1 << (16 + 6  ) | //sw_fb0_nvstr ;
                        0 << 7  | 1 << (16 + 7  ) | //sw_fb0_ifren ;
                        0 << 8  | 1 << (16 + 8  ) | //sw_fb0_reden ;
                        0 << 9  | 1 << (16 + 9  ) | //sw_fb0_ifren1;
                        1 << 10 | 1 << (16 + 10 ) | //sw_fb0_tmr   ;
                    slice1_sel  | 1 << (16 + 11 ) );//sw_fb0_sel   ;

  if ( slice0_sel | slice1_sel) delay1us(20); //100us

  word32(EFLASHC_SW_CONF, 0); //switch to hw mode
}

#endif

